/*
 * cuda_test.c
 *
 *  Created on: 01.06.2013
 *      Author: Eros
 */

#include <stdio.h>
#include <cuda.h>

// Thread auf der GPU
__global__ void square_array(float *a, int N)
{
  int idx = blockIdx.x * blockDim.x + threadIdx.x;
  if (idx<N) a[idx] = a[idx] * a[idx];
}

/*void CUDART_CB MyCallback(void *data){
    printf("Welcome back\n");
}*/

// Main-Fkt
int main(void)
{
	float *a_h, *a_d;  // Pointer to host & device arrays
	const int N = 10;  // Number of elements in arrays
	size_t size = N * sizeof(float);
	a_h = (float *)malloc(size);        // Allocate array on host
	cudaMalloc((void **) &a_d, size);   // Allocate array on device
	// Initialize host array and copy it to CUDA device
	for (int i=0; i<N; i++)
		a_h[i] = (float)i;
	cudaMemcpy(a_d, a_h, size, cudaMemcpyHostToDevice);
	// Do calculation on device:
	int block_size = 4;
	int n_blocks = N/block_size + (N%block_size == 0 ? 0:1);
	square_array <<< n_blocks, block_size >>> (a_d, N);
	// Retrieve result from device and store it in host array
	cudaMemcpy(a_h, a_d, sizeof(float)*N, cudaMemcpyDeviceToHost);
	//cudaStreamAddCallback(1, (cudaStreamCallback_t)MyCallback, NULL, 0);
	// Print results
	for (int i=0; i<N; i++) 
		printf("%d %f\n", i, a_h[i]);
	// Cleanup
	free(a_h); cudaFree(a_d);
}
